package com.heima.comment.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.heima.apis.user.IUserClient;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentLike;
import com.heima.comment.pojos.ApCommentRepay;
import com.heima.comment.pojos.ApCommentRepayLike;
import com.heima.comment.service.ApCommentReplyService;
import com.heima.comment.vos.ApCommentRepayVo;
import com.heima.common.exception.CustomException;
import com.heima.model.comment.dtos.CommentRepayDto;
import com.heima.model.comment.dtos.CommentRepayLikeDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.thread.AppThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * ClassName: ApCommentReplyServiceImpl
 * Description:
 * date: 2023/8/30 0030 15:53
 *
 * @author zHan
 */

@Service
@Slf4j
@Transactional(rollbackFor = Throwable.class)
public class ApCommentReplyServiceImpl implements ApCommentReplyService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IUserClient userClient;

    /**
     * 保存评论回复
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult save(CommentRepaySaveDto dto) {
        // 参数校验
        if (dto == null || dto.getCommentId() == null || StringUtils.isBlank(dto.getContent())) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // 评论内容大于140，报错
        if (dto.getContent().length() > 140) {
            return ResponseResult.errorResult(201, "评论内容不能大于140字");
        }
        // 判断用户是否登录
        ApUser apUser = AppThreadLocalUtil.getUser();
        if (apUser == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 根据用户id查询用户信息
        ResponseResult responseResult = userClient.getUserInfo(apUser.getId());
        if (responseResult.getCode().equals(200)) {
            String json = JSON.toJSONString(responseResult.getData());
            ApUser dbUser = JSON.parseObject(json, ApUser.class);
            // 封装对象
            ApCommentRepay apCommentRepay = new ApCommentRepay();
            apCommentRepay.setAuthorId(dbUser.getId());
            apCommentRepay.setAuthorName(dbUser.getName());
            apCommentRepay.setCommentId(dto.getCommentId());
            apCommentRepay.setContent(dto.getContent());
            apCommentRepay.setLikes(0);
            apCommentRepay.setCreatedTime(new Date());
            apCommentRepay.setUpdatedTime(new Date());
            // 执行新增方法
            mongoTemplate.save(apCommentRepay);
            // 更新评论数
            // 查询 ApComment
            ApComment apComment = mongoTemplate.findById(dto.getCommentId(), ApComment.class);
            // 数据不存在
            if (apComment == null) {
                throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
            }
            apComment.setReply(apComment.getReply() + 1);
            mongoTemplate.save(apComment);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 查询评论列表
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(CommentRepayDto dto) {
        // 检查参数
        if (dto == null || StringUtils.isBlank(dto.getCommentId())) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        if (dto.getSize() == null) {
            dto.setSize(10);
        }
        // 判断用户是否登录
        ApUser apUser = AppThreadLocalUtil.getUser();
        if (apUser == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 分页条件查询
        List<ApCommentRepay> commentRepayList =
                mongoTemplate.find(Query.query(Criteria.where("commentId").is(dto.getCommentId())
                                .and("createdTime").lt(dto.getMinDate()))
                        .limit(dto.getSize())
                        .with(Sort.by(Sort.Direction.DESC, "likes","createdTime")),
                        ApCommentRepay.class);
        // 查询当前评论中哪些数据被点赞了
        // 获取评论id集合
        List<String> idList = commentRepayList.stream()
                .map(ApCommentRepay::getId)
                .collect(Collectors.toList());
        // 查询评论点赞的集合
        List<ApCommentRepayLike> apCommentRepayLikeList = mongoTemplate.find(Query.query(Criteria.where(
                        "authorId").is(apUser.getId())
                .and("commentRepayId").in(idList)), ApCommentRepayLike.class);
        // 集合为空，直接返回
        if (CollectionUtils.isEmpty(apCommentRepayLikeList)) {
            return ResponseResult.okResult(commentRepayList);
        }
        // 点赞了，循环，封装ApCommentVo并返回
        List<ApCommentRepayVo> apCommentRepayVos = commentRepayList.stream().map(apCommentRepay -> {
            ApCommentRepayVo apCommentRepayVo = new ApCommentRepayVo();
            BeanUtils.copyProperties(apCommentRepay, apCommentRepayVo);
            apCommentRepayVo.setOperation((short) 0);
            return apCommentRepayVo;
        }).collect(Collectors.toList());
        // 结果返回
        return ResponseResult.okResult(apCommentRepayVos);
    }

    /**
     * 点赞评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentRepayLikeDto dto) {
        // 参数检验
        if (dto == null || StringUtils.isBlank(dto.getCommentRepayId()) || dto.getOperation() == null) {
            throw new CustomException(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        // 判断用户是否登录
        ApUser apUser = AppThreadLocalUtil.getUser();
        if (apUser == null) {
            throw new CustomException(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 查询CommentRepay
        ApCommentRepay apCommentRepay = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentRepay.class);
        // 数据不存在
        if (apCommentRepay == null) {
            throw new CustomException(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        // 点赞
        if (dto.getOperation() == 0) {
            // ap_comment_repay_like中新增数据
            ApCommentRepayLike apCommentRepayLike = new ApCommentRepayLike();
            apCommentRepayLike.setAuthorId(apUser.getId());
            apCommentRepayLike.setCommentRepayId(dto.getCommentRepayId());
            mongoTemplate.save(apCommentRepayLike);
            // ap_comment_repay中的like加1
            apCommentRepay.setLikes(apCommentRepay.getLikes() + 1);
        } else if (dto.getOperation() == 1) {
            // 取消点赞
            // ap_comment_like中删除数据
            mongoTemplate.remove(Query.query(Criteria.where("commentRepayId").is(dto.getCommentRepayId())),
                    ApCommentLike.class);
            // ap_comment中的like减1
            apCommentRepay.setLikes(apCommentRepay.getLikes() - 1);
        }
        // 修改 ApCommentRepay
        apCommentRepay.setUpdatedTime(new Date());
        mongoTemplate.save(apCommentRepay);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);

    }
}
